package com.filldream.fastboot.core.manager;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.filldream.fastboot.base.entity.MallCategory;
import com.filldream.fastboot.base.mapper.MallCategoryMapper;
import com.filldream.fastboot.base.request.pc.mallCategory.MallCategoryListSTO;
import com.filldream.fastboot.base.request.pc.mallCategory.MoveCategorySTO;
import com.filldream.fastboot.common.entity.B;
import com.filldream.fastboot.common.entity.ErrorCode;
import com.filldream.fastboot.common.entity.R;
import com.filldream.fastboot.core.cache.CacheMap;
import com.filldream.fastboot.core.cache.CacheObj;
import com.filldream.fastboot.core.cache.CacheUtil;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;

/**
 * @author RickSun && iFillDream
 * @version 1.0
 * @data 2020-05-27 9:30
 * @description TODO
 */
@AllArgsConstructor
@Service
@Transactional(rollbackFor = Exception.class)
public class MallCategoryManager {

    private MallCategoryMapper mallCategoryMapper;

    //根据ID获取缓存
    public MallCategory getById( Long id ){
        CacheObj<MallCategory> cache = CacheUtil.getCache(CacheMap.MALL_CATEGORY_DETAIL, MallCategory.class, id);
        if( cache.getData() != null ){
            return cache.getData();
        }
        MallCategory mallCategory = mallCategoryMapper.selectById(id);
        if( mallCategory != null ){
            CacheUtil.cacheObj( cache.getCacheKey(),mallCategory );
        }
        return mallCategory;
    }

    //获取子分类的ID集合(含自身)
    public List<Long> getChildIds( Long id,List<Long> resultIdList ){
        if(resultIdList == null || resultIdList.isEmpty()){
            resultIdList = new ArrayList<>();
        }
        if(!id.equals(0L)){ resultIdList.add(id);};
        List<MallCategory> list = mallCategoryMapper.selectList(new QueryWrapper<MallCategory>().eq("p_id", id));
        if(!list.isEmpty()){
            for (MallCategory mallCategory : list) {
                Long childId = mallCategory.getId();
                List<MallCategory> childMallCategory = mallCategoryMapper.selectList(new QueryWrapper<MallCategory>().eq("p_id", childId));
                if( childMallCategory.isEmpty() ){
                    resultIdList.add(childId);
                }else{
                    resultIdList.add(childId);
                    getChildIds(childId,resultIdList);
                }
            }
        }
        return resultIdList;
    }

    //添加商品分类
    public R<List<MallCategory>> list(MallCategoryListSTO mallCategoryListSTO ){
        QueryWrapper sql = new QueryWrapper();
        sql.eq("p_id",mallCategoryListSTO.getPId());
        sql.orderByDesc("cate_sort");
        List<MallCategory> list = mallCategoryMapper.selectList(sql);
        return R.successd(list);
    }

    //添加商品分类
    public R<MallCategory> add(MallCategory mallCategory ){
        mallCategory.setId(null);
        mallCategory.setCateSort( getSort(mallCategory.getPId()) );
        Integer addStatus = mallCategoryMapper.insert(mallCategory);
        return addStatus > 0 ? R.autoSuccess(mallCategory)
                : R.successd(ErrorCode.FAIL.reMsg(),mallCategory);
    }

    //修改商品分类
    public B modify(MallCategory mallCategory ){
        //原来的分类
        MallCategory nowCate = getById(mallCategory.getId());
        //是否从父级节点变成叶子节点
        if( mallCategory.getIsLeaf() != null && mallCategory.getIsLeaf().equals(1) && nowCate.getIsLeaf().equals(0) ){
            return B.fail(ErrorCode.BASE_ERR.reMsg("父级分类无法变成子级分类"));
        }
        //修改父级ID
        if( mallCategory.getPId() != null && !mallCategory.getPId().equals(nowCate.getPId()) ){
            MallCategory newMallCate = getById(mallCategory.getPId());
            //新父级不是叶子时，新父级不做修改
            //新父级是叶子，新父级做修改
            Integer newMallCateIsLeaf = newMallCate.getIsLeaf();
            if( newMallCateIsLeaf.equals(1) ){
                newMallCate.setIsLeaf(0);
                mallCategoryMapper.updateById(newMallCate);
                CacheUtil.delKey( CacheMap.getKey(CacheMap.MALL_CATEGORY_DETAIL,newMallCate.getId()) );
            }
            //给他提供一个新的排序
            mallCategory.setCateSort( getSort( mallCategory.getPId() ) );
        }
        CacheUtil.delKey( CacheMap.getKey(CacheMap.MALL_CATEGORY_DETAIL,mallCategory.getId()) );
        return B.checkSuccess(  mallCategoryMapper.updateById(mallCategory) );
    }

    //移动商品分类
    public B move(MoveCategorySTO moveCategorySTO ){
        MallCategory mallCategory = getById(moveCategorySTO.getId());
        QueryWrapper<MallCategory> example = new QueryWrapper();
        example.eq("p_id",mallCategory.getPId());
        //越小越大 升序 1 2 3 4 5 6
        example.orderByDesc("cate_sort");
        //上移
        if(moveCategorySTO.getMoveType().equals(1)){
            example.le("cate_sort",mallCategory.getCateSort());
        }else{
            example.ge("cate_sort",mallCategory.getCateSort());
        }
        example.last( " limit 0,2");
        List<MallCategory> mallCategories = mallCategoryMapper.selectList(example);
        if(mallCategories.size() < 2){
            return B.fail("移动失败");
        }else{
            MallCategory one = mallCategories.get(0);
            MallCategory two = mallCategories.get(1);
            Integer temp = two.getCateSort();

            two.setCateSort(one.getCateSort());
            one.setCateSort(temp);
            modify(one);
            modify(two);
            return B.success();
        }
    }

    //删除分类
    public B del(Long id ){
        //删除分类时注意商品是否使用到该分类，或该分类下是否有子分类
        //TODO 商品正在使用分类

        long count = mallCategoryMapper.selectCount(
                new QueryWrapper<MallCategory>().eq("p_id", id)
        );
        if( count > 0 ){
            return B.fail(ErrorCode.BASE_ERR.reMsg("请先删除当前分类下的" + count + "个子分类及其相关分类"));
        }
        CacheUtil.delKey( CacheMap.getKey(CacheMap.MALL_CATEGORY_DETAIL,id) );
        return B.checkSuccess( mallCategoryMapper.deleteById(id) );
    }

    //获取排序
    private Integer getSort(Long parentId){
        List<MallCategory> mallCategoryList = mallCategoryMapper.selectList(
                new QueryWrapper<MallCategory>()
                        .eq("p_id",parentId)
                        .orderByDesc("cate_sort").last( " limit 0,1")
        );
        if(mallCategoryList.isEmpty()){
            return 1;
        }else{
            return mallCategoryList.get(0).getCateSort() + 1;
        }
    }

}
